using SqlSugar;

namespace Repository;

/// <summary>
/// 基础仓储类
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <remarks>
/// 提供通用的CRUD数据访问实现，基于SqlSugar ORM
/// 支持动态更新（只更新非null字段）
/// </remarks>
public class BaseRepository<TEntity>(ISqlSugarClient db) where TEntity : class, new()
{
    /// <summary>
    /// 数据库客户端
    /// </summary>
    protected readonly ISqlSugarClient _db = db;
    /// <summary>
    /// 获取所有记录
    /// </summary>
    /// <returns>实体列表</returns>
    public async Task<List<TEntity>> GetAllAsync()
    {
        return await _db.Queryable<TEntity>().ToListAsync();
    }

    /// <summary>
    /// 根据ID获取单条记录
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <returns>实体对象，不存在则返回null</returns>
    /// <exception cref="ArgumentNullException">当id为null时抛出</exception>
    public async Task<TEntity> GetByIdAsync(object id)
    {
        if (id == null)
            throw new ArgumentNullException(nameof(id), "ID不能为空");
            
        return await _db.Queryable<TEntity>().InSingleAsync(id);
    }

    /// <summary>
    /// 添加单条记录
    /// </summary>
    /// <param name="entity">要添加的实体</param>
    /// <returns>添加后的实体（包含生成的ID）</returns>
    /// <exception cref="ArgumentNullException">当entity为null时抛出</exception>
    public async Task<TEntity> AddAsync(TEntity entity)
    {
        if (entity == null)
            throw new ArgumentNullException(nameof(entity), "实体对象不能为空");
            
        await _db.Insertable(entity).ExecuteCommandAsync();
        return entity;
    }

    /// <summary>
    /// 更新记录（动态更新，只更新非空字段）
    /// </summary>
    /// <param name="entity">要更新的实体</param>
    /// <returns>是否更新成功</returns>
    /// <exception cref="ArgumentNullException">当entity为null时抛出</exception>
    /// <remarks>
    /// 使用IgnoreNullColumns忽略null值字段，只更新有值的字段
    /// </remarks>
    public async Task<bool> UpdateAsync(TEntity entity)
    {
        if (entity == null)
            throw new ArgumentNullException(nameof(entity), "实体对象不能为空");
            
        return await _db.Updateable(entity)
            .IgnoreNullColumns()
            .ExecuteCommandAsync() > 0;
    }

    /// <summary>
    /// 根据ID删除记录
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <returns>是否删除成功</returns>
    /// <exception cref="ArgumentNullException">当id为null时抛出</exception>
    public async Task<bool> DeleteByIdAsync(object id)
    {
        if (id == null)
            throw new ArgumentNullException(nameof(id), "ID不能为空");
            
        return await _db.Deleteable<TEntity>().In(id).ExecuteCommandAsync() > 0;
    }
}